home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 52
/
Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso
/
Aminet
/
misc
/
emu
/
Apex-src.lha
/
TERMA.XPL
< prev
next >
Wrap
Text File
|
2001-09-30
|
12KB
|
432 lines
\TERMA.XPL JUL-01-88 VERSION 1.0x5 (SEE MAIN)
\TERMINAL SIMULATOR PROGRAM
\BY LOREN BLANEY
\REVISION HISTORY:
\OCT-08-87, ORIGINAL RELEASED TO DFM.
\OCT-09-87, V1.0x1, ECHO IN SEND MODE, CTXT.
\DEC-17-87, V1.0X2,
\FEB-03-88, V1.0X3, CHANGED COMMANDS, WILL WRITE OUTPUT FILE IN HEX MODE.
\JUN-03-88, V1.0X4, FIX BLOW UP CAUSED BY BUFFER OVERFLOW.
\JUN-27-88, V1.0X5, MODIFIED FOR THE AMIGA.
\WARNING:
\This program is not finished (are they ever?). There is no parity, and
\ the HALFSEC has not been adjusted.
\This program is extremely slow when receiving and displaying data.
\Higher baud rates can be used if the display is turned off. Also there
\ may be a problem with handshake - the XOFF is overwritten perhaps before
\ it is through transimtting. (RED RYDER didn't work with the Apple version.)
\NOTES:
\No handler is required for the serial device. Only XON/XOFF handshake
\ protocol is used here, thus only three of the RS-232 lines need to be
\ connected (pins 2, 3, and 7).
code REM= 2, RESERVE= 3, CHIN= 7, CHOUT= 8,
CRLF= 9, TEXT= 12, OPENI= 13, OPENO= 14,
CLOSE= 15, CURSOR= 23, PEEK_W= 113, POKE_W= 114,
GETKEY= 125, KEYHIT= 126;
def BUFSIZE= 10000, \BUFFER SIZE IN BYTES
HALFSEC= 5000; \CONSTANT TO DELAY 1/2 SECOND (H/W DEPENDENT)
def SERDATR= $DFF018,
SERDAT= $DFF030,
SERPER= $DFF032,
INTREQ= $DFF09C;
def BEL= $07, CR= $0D, FF= $0C, XON= $11, XOFF= $13, EOF= $1A, SP= $20;
def DN= $0A, UP= $0B, CTRL_S= $13, CTRL_W= $17; \UP AND DOWN ARROWS
def LT= $08, RT= $15, CTRL_A= $01, CTRL_Q= $11; \LEFT AND RIGHT ARROWS
int PARAMS, \ARRAY OF PARAMETERS: BAUD RATE, ETC.
CHAR, \CHARACTER
TIMER, \TO CONTINUE COLLECTING DATA 1/2 SEC AFTER XOFF IS SENT
TIMING, \FLAG: "TIMER" IS ACTIVE
COLLECT, \FLAG: COLLECT DATA FOR OUTPUT FILE
GOTSOME, \FLAG: SOME DATA HAS BEEN COLLECTED
HALFDUP, \FLAG: HALF DUPLEX, DISPLAY CHARACTERS SENT OUT RS-232
DISPON, \FLAG: DISPLAY RECEIVED CHARACTERS ON THE SCREEN
HEXON, \FLAG: CONVERT RECEIVED CHARACTERS TO HEX FORMAT
STATUS, \STATUS BYTE READ FROM STATUS REGISTER
BUFINX, \INDEX INTO "BUFFER", USUALLY POINTS TO AN EMPTY LOCATION
STOPBITS, \MASK TO "OR" IN DATA BITS
DATABITS, \MASK TO RECEIVE ONLY THE SPECIFIED NUMBER OF DATA BITS
II; \SCRATCH FOR MAIN
addr BUFFER, \BUFFER FOR RECEIVING TEXT FILES
HEXDIGIT; \ARRAY TO CONVERT BINARY TO ASCII HEX
\----------------------------------------------------------------------
proc FATAL(STR);
addr STR;
begin
CURSOR(0, 23);
CHOUT(0, BEL);
TEXT(0, "
FATAL ERROR - ");
TEXT(0, STR);
CRLF(0);
exit;
end; \FATAL
proc CTXT(X, Y, STR); \MOVE CURSOR AND DISPLAY TEXT ON CRT
int X, Y;
addr STR;
begin
CURSOR(X, Y);
TEXT(0, STR);
end; \CTXT
func DOPARITY(BYTE); \SET THE PARITY BIT ACCORDING TO PARAMS(1)
int BYTE;
reg int I, B, P;
int MASK1, MASK2, SIZE;
begin
if PARAMS(3) = 1 then return BYTE; \RETURN IF NO PARITY
MASK1:= [0, $80, $100]; \SIZE: 7, 8
MASK2:= [0, $7F, $FF]; \SIZE: 7, 8
B:= BYTE;
P:= 0;
SIZE:= PARAMS(1); \1: 7 BITS, 2: 8 BITS
for I:= 1, SIZE+6 do
begin
B:= B <<1;
P:= P |B;
end;
if PARAMS(3)=2 \ODD PARITY\ then P:= not P; \1: NONE, 2:ODD, 3: EVEN
return (P & MASK1(SIZE)) ! (BYTE & MASK2(SIZE));
end; \DOPARITY
\----------------------------------------------------------------------
proc BUFOUT(CH); \OUTPUT "CH" TO BUFFER
int CH;
begin
BUFFER(BUFINX):= CH;
BUFINX:= BUFINX +1;
if BUFINX >= BUFSIZE -30 then \10 = SAFETY MARGIN FOR XOFF RESPONSE
begin \BUFFER IS FULL
if BUFINX >= BUFSIZE then FATAL("DID NOT STOP ON XOFF COMMAND");
POKE_W(SERDAT, XOFF !STOPBITS); \SEND XOFF (BUG??? - WAIT FOR READY)
TIMER:= HALFSEC; \START TIMER
TIMING:= true;
end;
end; \BUFOUT
\----------------------------------------------------------------------
proc DOEXIT; \CLOSE ANY OUTPUT FILE AND EXIT PROGRAM
int I;
begin
if GOTSOME then
begin
for I:= 0, BUFINX-1 do CHOUT(3,BUFFER(I));
CLOSE(3);
end;
CURSOR(0, 23);
exit;
end; \DOEXIT
\----------------------------------------------------------------------
proc SENDFILE; \SEND THE INPUT FILE OUT THE SERIAL PORT
int CH, \CHARACTER TO SEND
KEY, \KEYSTROKE
CHREC, \CHARACTER RECEIVED
STAT; \STATUS BYTE
begin
OPENI(3);
STAT:= 0;
loop begin
CH:= CHIN(3);
if CH = EOF then quit;
if STAT & $4000 then \CHAR HAS BEEN RECEIVED FROM SERIAL PORT
begin
CHREC:= PEEK_W(SERDATR) & DATABITS;
POKE_W(INTREQ, $0800); \CLEAR REC. BUF. FULL STATUS
if CHREC = XOFF then
begin
loop begin \WAIT FOR XON
if PEEK_W(SERDATR) & $4000 then
\CLEAR REC. BUF. FULL STATUS
[POKE_W(INTREQ, $0800);
if (PEEK_W(SERDATR) &DATABITS) = XON
then quit];
if KEYHIT then
begin
KEY:= GETKEY;
if KEY = $98 then DOEXIT; \CTRL-X
if KEY = $83 then exit; \CTRL-C
end;
end;
POKE_W(INTREQ, $0800); \CLEAR REC. BUF. FULL STATUS
end
else [CHOUT(0, CHREC); \DISPLAY ANY RECEIVED CHAR
POKE_W(INTREQ, $0800)]; \CLEAR REC. BUF. FULL STATUS
end;
if KEYHIT then
begin
KEY:= GETKEY;
if KEY = $98 then DOEXIT; \CTRL-X
if KEY = $83 then exit; \CTRL-C
end;
if HALFDUP then CHOUT(0, CH); \SHOW CHAR THAT WAS SENT
\WAIT FOR XMITTER DATA REG EMPTY:
repeat STAT:= PEEK_W(SERDATR) until STAT & $2000;
POKE_W(SERDAT, CH !STOPBITS);
end;
end; \SENDFILE
\----------------------------------------------------------------------
proc SETUP; \SET UP TERMINAL PARAMETERS
int ENTRY, \PARAMETER ENTRY NUMBER
KEY, \CHARACTER FROM KEYBOARD
BAUD, DATAB, STOPB, PARITY, DUPLEX, DISPLAY, HEX; \ARRAYS
func SEL(S, X, Y, A); \RETURN A SELECTED PARAMETER
int S, \INITIAL SELECTION
X, Y, \SCREEN COORDINATES
A; \ARRAY OF SELECTIONS (TEXT STRINGS)
begin
loop begin
CTXT(X, Y, A(S)); \DISPLAY SELECTION
CURSOR(X, Y); \FOR NEATNESS
KEY:= CHIN(1);
if KEY=SP ! KEY=CR then S:= S +1 else quit;
if S > A(0) then S:= 1;
end;
CTXT(X, Y, A(S)); \OVERWRITE GARBAGE LEFT BY CHIN
return S;
end; \SEL
begin \SETUP
CHOUT(0, FF);
TEXT(0," -- PARAMETER SET UP --
Select parameters with arrow keys (or CTRL-W and CTRL-S).
Select options with space bar (or RETURN key).
Press CTRL-P to save selected options (APX>SAVE TERM).
Baud rate: Duplex:
Data bits: Display:
Stop bits: Hex:
Parity:
-- OTHER COMMANDS --
CTRL-@ - Enter or exit Parameter Set Up mode.
CTRL-R - Start (or Resume) collecting data in output file.
CTRL-F - Finish collecting data.
CTRL-Y - Send input file.
CTRL-^^ - Send next CTRL character regardless.
CTRL-X - Save file and return to Apex.");
\NUMBER OF SELECTIONS, STRINGS DESCRIBING SELECTIONS:
BAUD:= [ 14, " 110", " 135", " 150", " 300", " 600", " 1200", " 1800",
" 2400", " 3600", " 4800", " 7200", " 9600", "19200", "38400"];
DATAB:= [2, "7", "8"];
STOPB:= [2, "1", "2"];
\PARITY:= [3, "NONE", "ODD ", "EVEN"];
PARITY:= [3, "NONE", "NONE", "NONE"]; \*** DEBUG ***
DUPLEX:= [2, "FULL", "HALF"];
DISPLAY:= [2, "ON ", "OFF"];
HEX:= [2, "ON ", "OFF"];
CTXT(24, 9, BAUD(PARAMS(0))); \DISPLAY CURRENT VALUES
CTXT(24, 10, DATAB(PARAMS(1)));
CTXT(24, 11, STOPB(PARAMS(2)));
CTXT(24, 12, PARITY(PARAMS(3)));
CTXT(64, 9, DUPLEX(PARAMS(4)));
CTXT(64, 10, DISPLAY(PARAMS(5)));
CTXT(64, 11, DISPLAY(PARAMS(6)));
ENTRY:= 0;
loop begin \GET NEW VALUES
case ENTRY of
0: PARAMS(0):= SEL(PARAMS(0), 24, 9, BAUD);
1: PARAMS(1):= SEL(PARAMS(1), 24, 10, DATAB);
2: PARAMS(2):= SEL(PARAMS(2), 24, 11, STOPB);
3: PARAMS(3):= SEL(PARAMS(3), 24, 12, PARITY);
4: PARAMS(4):= SEL(PARAMS(4), 64, 9, DUPLEX);
5: PARAMS(5):= SEL(PARAMS(5), 64, 10, DISPLAY);
6: PARAMS(6):= SEL(PARAMS(6), 64, 11, HEX)
other;
case KEY of
DN, CTRL_S: ENTRY:= ENTRY +1;
UP, CTRL_W: ENTRY:= ENTRY -1;
\This only works when there are 7 entries:
RT, CTRL_A: ENTRY:= ENTRY + (if ENTRY >= 4 then -3 else 4);
LT, CTRL_Q: ENTRY:= ENTRY + (if ENTRY >= 4 then -4 else 3);
$00: quit; \CTRL-@ - BACK TO TERMINAL MODE
$18: DOEXIT \CTRL-X - EXIT BACK TO APEX
other CHOUT(0, BEL); \BEEP ON ILLEGAL KEYS
if ENTRY > 6 then ENTRY:= 0; \WRAP AROUND
if ENTRY < 0 then ENTRY:= 6;
end;
CHOUT(0, FF); \CLEAR SCREEN WHEN GOING TO TERMINAL MODE
end; \SETUP
\----------------------------------------------------------------------
proc INITIALIZE; \INITIALIZE SERIAL REGISTERS AND PARAMETERS
int BAUD;
begin
BAUD:= [0, 110, 135, 150, 300, 600, 1200, 1800,
2400, 3600, 4800, 7200, 9600, 19200, 38400];
\N = 1E9 /(BAUD_RATE *279.4) -1 = 3579098 /BAUD_RATE -1
POKE_W(SERPER, 3579098 /BAUD(PARAMS(0)) -1); \(LONG IS OFF = 8 BIT BYTES)
STOPBITS:= $0100; \1 STOP BIT
if PARAMS(2) = 2 then STOPBITS:= $0300; \2 STOP BITS
\ASSUME 8 DATA BITS PER BYTE
DATABITS:= $FF;
\IF 7 BITS PER BYTE THEN SHIFT STOP BITS LEFT ONE BIT
if PARAMS(1) = 1 then
begin
STOPBITS:= STOPBITS >>1;
DATABITS:= $7F;
end;
\PARITY IS ALWAYS NONE
\PARITY: 1=NONE, 2=ODD, 3=EVEN
\if PARAMS(3) # 1 then STOPBITS:= STOPBITS <<1;
POKE_W(INTREQ, $0800); \CLEAR REC. BUF. FULL STATUS
HALFDUP:= PARAMS(4) = 2; \INIT OTHER PARAMETERS
DISPON:= PARAMS(5) = 1;
HEXON:= PARAMS(6) = 1;
end; \INITIALIZE
\----------------------------------------------------------------------
begin \MAIN
PARAMS:= [6, 2, 1, 1, 1, 1, 2]; \SET UP FOR INITIAL DEFAULTS:
\ 1200 BAUD, 8 DATA, 1 STOP, NO PARITY, FULL DUPLEX, DISPLAY ON, HEX OFF
HEXDIGIT:= "0123456789ABCDEF";
BUFFER:= RESERVE(BUFSIZE);
COLLECT:= false;
GOTSOME:= false;
TIMING:= false;
INITIALIZE;
TEXT(0, "-- TERMINAL SIMULATOR, V1.0x5 --
Press CTRL-@ to set up parameters.
");
loop begin
if KEYHIT then \A KEY WAS HIT
begin
CHAR:= GETKEY;
case CHAR of
$00: [SETUP; INITIALIZE]; \CTRL-@: SET UP PARAMETERS
$12: begin
COLLECT:= true; \CTRL-R: RESUME COLLECTING DATA
if not GOTSOME then \FIRST CTRL-R
begin
GOTSOME:= true; \ASSUME WE'LL GET SOMETHING
OPENO(3);
BUFINX:= 0;
end;
end;
$06: COLLECT:= false; \CTRL-F: FINISH COLLECTING DATA
$19: SENDFILE; \CTRL-Y: SEND THE INPUT FILE
$1E: begin \CTRL-^: ALWAYS SEND NEXT CHAR
repeat until KEYHIT; \WAIT FOR KEYHIT
CHAR:= GETKEY;
POKE_W(SERDAT, CHAR !STOPBITS); \SHOULD BE READY
if HALFDUP then CHOUT(0, CHAR);
end;
$18: DOEXIT; \CTRL-X: SAVE FILE AND EXIT
$03: exit \CTRL-C: JUST EXIT
other begin
POKE_W(SERDAT, CHAR !STOPBITS); \SHOULD BE READY, SLOW HUMANS
if HALFDUP then CHOUT(0, CHAR);
end;
end;
STATUS:= PEEK_W(SERDATR);
if STATUS & $4000 then \CHAR RECEIVED FROM SERIAL PORT
begin
if STATUS & $8000 then CHOUT(0,^#); \OVERRUN ERROR
CHAR:= PEEK_W(SERDATR) &DATABITS;
POKE_W(INTREQ, $0800); \CLEAR REC. BUF. FULL STATUS
if DISPON then
if HEXON then
begin
CHOUT(0, HEXDIGIT(CHAR>>4));
CHOUT(0, HEXDIGIT(CHAR&$0F));
CHAR:= CHAR & $7F;
if CHAR>=$20 & CHAR<=$7E then CHOUT(0, CHAR)
else CHOUT(0, ^.);
CHOUT(0, SP);
end
else CHOUT(0, CHAR);
if COLLECT then
begin
if HEXON then
begin
BUFOUT(HEXDIGIT(CHAR>>4));
BUFOUT(HEXDIGIT(CHAR&$0F));
CHAR:= CHAR & $7F;
if CHAR>=$20 & CHAR<=$7E then BUFOUT(CHAR)
else BUFOUT(^.);
BUFOUT(SP);
end
else begin \("BUFOUT" INLINED FOR SPEED)
BUFFER(BUFINX):= CHAR;
BUFINX:= BUFINX +1;
if BUFINX >= BUFSIZE -30 then
begin \BUFFER IS FULL
if BUFINX >= BUFSIZE then
FATAL("DID NOT STOP ON XOFF COMMAND");
POKE_W(SERDAT, XOFF !STOPBITS);
TIMER:= HALFSEC; \START TIMER
TIMING:= true;
end;
end;
end;
end;
if TIMING then
begin
TIMER:= TIMER -1;
if TIMER <= 0 then \TIMED OUT (SENDER BETTER HAVE STOPPED
begin \ BY NOW)
for II:= 0, BUFINX-1 do CHOUT(3, BUFFER(II));
BUFINX:= 0;
POKE_W(SERDAT, XON !STOPBITS); \(SHOULD BE READY)
TIMING:= false;
end;
end;
end; \LOOP
end; \MAIN
FINX:= 0;